package com.loong.seller.handler;

import com.loong.common.enumerate.ShopDeliveryRuleType;
import com.loong.common.executor.BatchExecutor;
import com.loong.common.google.param.DirectionsParam;
import com.loong.common.google.place.PlaceUtils;
import com.loong.common.google.result.DistanceDurationResult;
import com.loong.common.utils.TransformUtils;
import com.loong.seller.business.ShopDeliveryRuleBusiness;
import com.loong.seller.common.backend.param.ShopDeliveryRuleParam;
import com.loong.seller.common.forehead.param.ShopDeliveryPriceQueryForeheadParam;
import com.loong.seller.dto.ShopForeheadConsumerResult;
import com.loong.seller.model.ShopDelivery;
import com.loong.seller.model.ShopDeliveryRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Description:
 * @Author: hzp
 * @Date: 2020-12-16 14:12
 */
@Component
@Slf4j
public class ShopDeliveryRuleHandler {
    @Resource
    private BatchExecutor batchExecutor;
    @Resource
    private ShopDeliveryRuleBusiness shopDeliveryRuleBusiness;
    @Resource
    private ShopDeliveryHandler shopDeliveryHandler;
    @Resource
    private PlaceUtils placeUtils;

    public void save(ShopDeliveryRuleParam param) {
        shopDeliveryRuleBusiness.save(TransformUtils.transform(param, ShopDeliveryRule.class));
    }

    public void update(ShopDeliveryRuleParam param) {
        shopDeliveryRuleBusiness.updateByPrimaryKeySelective(TransformUtils.transform(param, ShopDeliveryRule.class));
    }

    public void delete(List<Long> ids) {
        batchExecutor.batchExecute(ids,id->id.toString(),id->shopDeliveryRuleBusiness.deleteById(id));
    }

    public List<ShopDeliveryRule> findShopDeliveryRuleByShopId(Long shopId){
        return shopDeliveryRuleBusiness.findAllBy("shopId", shopId);
    }


    public static void main(String[] args) {
        try {
//            00:05:00-07:30:00
            String str="14:05:50.111";
            String str2="00:05:00.111";
            LocalTime of = LocalTime.of(14, 05);
            LocalTime parse = LocalTime.parse(str);
            LocalTime parse2 = LocalTime.parse(str2);
            System.out.println(parse);
            System.out.println(parse2);
//            LocalTime time = LocalTime.now();
//            System.out.println(time);
//            Thread.sleep(1_000);
//            LocalTime time2 = LocalTime.now();
//            System.out.println(time2);
//            int i = of.compareTo(time2);
//            int i1 = time2.compareTo(time);
//            System.out.println(i1);
//            System.out.println(i);
//            //add null NullPointerException
////            BigDecimal bigDecimal = new BigDecimal(1);
////            BigDecimal add = bigDecimal.add(null);
////            System.out.println(add);
//            System.out.println(new BigDecimal(2));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public List<ShopForeheadConsumerResult> resultConsumer(List<ShopForeheadConsumerResult> results) {
        if(CollectionUtils.isEmpty(results))return null;
        return results.stream()
                .map(shop-> shopResultConsumer(shop))
                .sorted(Comparator.comparing(ShopForeheadConsumerResult::getDistance))
                .collect(Collectors.toList());
    }

    private ShopForeheadConsumerResult shopResultConsumer(ShopForeheadConsumerResult shopForeheadResult){
        Long shopId = shopForeheadResult.getId();
        //配送方式列表
        // List<DeliveryWays> deliveryWaysBys = deliveryWaysHandler.findDeliveryWaysByShopId(shopId);
        List<ShopDelivery> byCondition = shopDeliveryHandler.findByCondition(shopId, true);
        //如果没有选择默认的 配送方式 就不显示配送费
        if(CollectionUtils.isEmpty(byCondition)) return shopForeheadResult;
        ShopDelivery shopDelivery = byCondition.get(0);
        if(ObjectUtils.isEmpty(shopDelivery.getBasePrice())||shopDelivery.getBasePrice().compareTo(BigDecimal.ZERO)<0)return shopForeheadResult;
        BigDecimal calculateDeliveryPrice = calc(shopDelivery, shopForeheadResult.getDistance());
        shopForeheadResult.setDeliveryPrice(calculateDeliveryPrice);
        return shopForeheadResult;
    }

    public BigDecimal getShopDeliveryPrice(ShopDeliveryPriceQueryForeheadParam param){
        Long shopId = param.getShopId();
        //配送方式列表
        // List<DeliveryWays> deliveryWaysBys = deliveryWaysHandler.findDeliveryWaysByShopId(shopId);
        List<ShopDelivery> byCondition = shopDeliveryHandler.findByCondition(shopId, true);
        ShopDelivery shopDelivery = byCondition.get(0);
        BigDecimal deliveryPrice = new BigDecimal(0);
        //如果没有选择默认的 配送方式 就不显示配送费 或者 0
        if(ObjectUtils.isEmpty(shopDelivery.getBasePrice())||shopDelivery.getBasePrice().compareTo(BigDecimal.ZERO)<0)return deliveryPrice;
        return calc(shopDelivery,param.getDistance());
    }

    private BigDecimal calc(ShopDelivery shopDelivery,String distance){
        //店铺所有规则
        List<ShopDeliveryRule> rules = findShopDeliveryRuleByShopId(shopDelivery.getShopId());
        //ruleType  维度 1-->时间  2-->距离
        Map<Integer, List<ShopDeliveryRule>> ruleTypeMap = rules.stream().collect(Collectors.groupingBy(ShopDeliveryRule::getRuleType, Collectors.toList()));
        List<ShopDeliveryRule> shopDeliveryRules_time = ruleTypeMap.get(ShopDeliveryRuleType.TIME.getCode());
        List<ShopDeliveryRule> shopDeliveryRules_distance = ruleTypeMap.get(ShopDeliveryRuleType.DISTANCE.getCode());
        BigDecimal calculateDeliveryPrice = shopDelivery.getBasePrice();
        int counter = 0;
        //时间维度
        if(!CollectionUtils.isEmpty(shopDeliveryRules_time)){
            for (ShopDeliveryRule rule:shopDeliveryRules_time) {
                //ruleRange == 14:05:50-16:05:50
                String[] ruleArray = rule.getRuleRange().split("-");
                String startTimeStr = ruleArray[0];
                String endTimeStr = ruleArray[1];
                LocalTime startTime = LocalTime.parse(startTimeStr);
                LocalTime endTime = LocalTime.parse(endTimeStr);
                //当前时间
                LocalTime nowTime = LocalTime.now();
                if(nowTime.compareTo(startTime)>=0&&nowTime.compareTo(endTime)<0){
                    calculateDeliveryPrice=calculateDeliveryPrice.add(calculateDeliveryPrice(rule, shopDelivery));
                    counter++;
                    break;
                }

            }

        }
        if(!CollectionUtils.isEmpty(shopDeliveryRules_distance)){
            //距离维度
            //距离 单位米 ruleRange ==> 1000-3000
            double distanceDouble=Double.parseDouble(distance);
            for (ShopDeliveryRule rule:shopDeliveryRules_distance) {
                String[] ruleArray = rule.getRuleRange().split("-");
                String minStr = ruleArray[0];
                String maxStr = ruleArray[1];
                if(distanceDouble>=Double.parseDouble(minStr)&&distanceDouble<Double.parseDouble(maxStr)){
                    calculateDeliveryPrice=calculateDeliveryPrice.add(calculateDeliveryPrice(rule, shopDelivery));
                    counter++;
                    break;
                }
            }
        }
        //减去多加的basePrice
        if(counter>0){
            calculateDeliveryPrice= calculateDeliveryPrice.subtract(new BigDecimal(counter).multiply(shopDelivery.getBasePrice()));
        }

        return calculateDeliveryPrice;
    }



    private BigDecimal calculateDeliveryPrice(ShopDeliveryRule rule,ShopDelivery shopDelivery){
        BigDecimal calculateDeliveryPrice;
        if(ObjectUtils.isEmpty(rule.getRuleValue())||rule.getRuleValue().compareTo(BigDecimal.ZERO)<=0){
            return shopDelivery.getBasePrice();
        }
        switch (rule.getRuleAction()) {
            case "add":
                calculateDeliveryPrice = shopDelivery.getBasePrice().add(rule.getRuleValue());
                break;
            case "subtract":
                calculateDeliveryPrice = shopDelivery.getBasePrice().subtract(rule.getRuleValue());
                break;
            case "multiply":
                calculateDeliveryPrice = shopDelivery.getBasePrice().multiply(rule.getRuleValue());
                break;
            case "divide":
                calculateDeliveryPrice = shopDelivery.getBasePrice().divide(rule.getRuleValue());
                break;
            default:
                calculateDeliveryPrice = shopDelivery.getBasePrice();
                break;
        }
        return calculateDeliveryPrice;

    }

    public DistanceDurationResult getDistance(DirectionsParam directionsParam) {
        DistanceDurationResult distance = placeUtils.getDistance(directionsParam);
       return distance;
    }
}
